package mvc;

import geographer.City;
import geographer.City;
import geographer.Continent;
import geographer.Country;
import geographer.Database;
import geographer.GeoGrapher;
import geographer.WorldMap;
import geographer.GeographicRegion;
import geographer.PartitionBar;

import geographer.Point;
import geographer.WorldMap;
import geographer.Database.Region;
import geographer.Database.Region;


import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

import java.util.LinkedList;
import java.util.List;

import java.util.List;


import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class SelectContainer extends JFrame implements ActionListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	/*
	 * The JList of the regions we want the user to select from
	 */
	JList<String> regionList;
	JButton selectButton;
	List<?> regions;
	
	Database.Region r;
	
	SelectionView view;
	String type;
	
	String selectedValue;
	
	public SelectContainer(Database.Region r,String type, SelectionView parent) {
		this.type =type;
		this.r = r;
		this.view = parent;
		//if(r.equals(Region.CITY) && type.equals("Map"))
			//return;
		
		
		JPanel buttonPanel = new JPanel();
		//JList<String> listOfRegions;
		
		if (r == Database.Region.CONTINENT) {
			regionList = new JList<String>(GeoGrapher.data.getKeys(Database.Region.CONTINENT).
					toArray(new String[GeoGrapher.data.getKeys(Database.Region.CONTINENT).size()]));
		} else if (r == Database.Region.COUNTRY) {
			regionList = new JList<String>(GeoGrapher.data.getKeys(Database.Region.COUNTRY).
					toArray(new String[GeoGrapher.data.getKeys(Database.Region.COUNTRY).size()]));
		} else if (r == Database.Region.CITY) {
			regionList = new JList<String>(GeoGrapher.data.getKeys(Database.Region.CITY).
					toArray(new String[GeoGrapher.data.getKeys(Database.Region.CITY).size()]));
		} else {
			 regionList = new JList<String>();
		}
		//regionList = listOfRegions;
		JScrollPane jSP = new JScrollPane(regionList);
		//regionList=listOfRegions;
		//JScrollPane jSP = new JScrollPane(listOfRegions);
		selectButton = new JButton("Select Region");
		selectButton.addActionListener(this);
		buttonPanel.add(selectButton);
		
		this.setTitle("Select your region");
		this.setSize(500, 300);
		this.add(jSP, BorderLayout.NORTH);
		this.add(buttonPanel, BorderLayout.SOUTH);
		this.setVisible(true);

	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		

		if(!type.equals("Map")){
		this.selectedValue = regionList.getSelectedValue().toString();

		
		//Instantiate the frame
		JFrame frame = new JFrame("GeoGrapher :: Partition");
		frame.setSize(800, 700);
		
		//Calculate the values to be used with the graph
		//The width of the graph
		int width = frame.getWidth()/2;
		
		//The top right corner of the graph
		int posX = frame.getWidth()/4;
		
		//The overall height of the graph
		int height = frame.getHeight()-20;
		
		//Fill the data list
		List<String> data;
		
		switch(r){
			case CONTINENT: data = ((Continent)Database.regions.get(selectedValue)).getSubregions(); break;
			case COUNTRY: data = ((Country)Database.regions.get(selectedValue)).getSubregions(); break;
			default:
				data = null;
		}
		switch(type){
			case "Area": Collections.sort(data, GeographicRegion.AR);
			case "Population": Collections.sort(data, GeographicRegion.PO);
		}
		
		
		
		//Instantiate, add, and show the frame with the graph
		PartitionBar bar = new PartitionBar(width,height,posX, data, type);
		JPanel graph = new JPanel(new BorderLayout());
		graph.add(new JLabel("Countries within a continent by Area", null, JLabel.CENTER), BorderLayout.NORTH);
		graph.add(bar, BorderLayout.CENTER);
		frame.add(graph);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
		}
		else{
			//Instantiate the frame
			JFrame worldFrame = new JFrame("Geographer :: World Map");
			
			//The world map to be displayed
			WorldMap map =  new WorldMap();
			
			selectedValue = regionList.getSelectedValue().toString();
			
			List<String> data;
			
			switch(r){
				case CONTINENT: selectedValue = regionList.getSelectedValue().toString();
					data = new LinkedList<String>();
									for(String country: ((Continent)Database.regions.get(selectedValue)).getSubregions())
										data.addAll(((Country)Database.regions.get(country)).getSubregions());break;
				case COUNTRY:selectedValue = regionList.getSelectedValue().toString();
					data = ((Country)Database.regions.get(selectedValue)).getSubregions(); break;
				case CITY: data = Database.getKeys(Database.Region.CITY);break;
				case POINT: data = ((Country)Database.regions.get(selectedValue)).getSubregions(); break;
				default:
					data = null;
					break;
			}
			
			//Loop through the hash map to get the relevante values
			for(String reg: data)
			{
				//Collect then City value
				switch(r){
				case CONTINENT:
				case COUNTRY:
				case CITY: try
				{
					City city = (City)Database.regions.get(reg);
					map.addPoint(city.getName(),city.getLat(),city.getLon());
				}catch(NullPointerException e3)
				{
					//Inform the user of an error
					//System.out.println(city.getName()+" does not have an associated latitude or longitude.");
					
				}
				break;
				case POINT: try
				{
					Point city = (Point)Database.regions.get(reg);
					map.addPoint(city.getName(),city.getLat(),city.getLon());
				}catch(NullPointerException e1)
				{
					//Inform the user of an error
					//System.out.println(city.getName()+" does not have an associated latitude or longitude.");
				}break;
				default:break;
			}
				
				//Add the points to the map
				
			}
			
			//Show the map
			JPanel graph = new JPanel(new BorderLayout());
			graph.add(map, BorderLayout.CENTER);
			graph.add(new JLabel(r+"S on the World Map", null, JLabel.CENTER), BorderLayout.NORTH);
			worldFrame.add(map);
			worldFrame.setSize(1300, 685);
			worldFrame.setLocationRelativeTo(null);
			worldFrame.setVisible(true);
			
			
		}
	}
	
	public String getSelectValue() {
		return this.selectedValue;
	}
}
